import { useLayoutStore } from '/@/store/modules/layout'
import axios, { AxiosError } from 'axios'
import { AxiosResponse } from 'axios'
import { ElLoading, ElNotification } from 'element-plus'
// axios重试插件
import axiosRetry from 'axios-retry'

let loading: { close(): void }

// 创建 axios 实例

const request = axios.create({
    // API 请求的默认前缀
    // baseURL: '/api',
    baseURL: 'http://127.0.0.1:8080/api',
    timeout: 60000 // 请求超时时间
})

// axios重试插件
axiosRetry(request, { retries: 3 })

// 异常拦截处理器
const errorHandler = (error: AxiosError<IResponse>) => {
    loading.close()
    const { getStatus, logout } = useLayoutStore()

    if (error.response?.status === 401) {
        if (getStatus.ACCESS_TOKEN) {
            logout()
        }
    }
    ElNotification({
        title: '请求失败',
        message: error.response?.data?.message || '请求失败',
        type: 'error'
    })
    return Promise.reject(error)
}

// request interceptor
request.interceptors.request.use(config => {
    const { getStatus } = useLayoutStore()
    loading = ElLoading.service({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.4)'
    })
    const token = getStatus.ACCESS_TOKEN
    // 如果 token 存在
    // 让每个请求携带自定义 token 请根据实际情况自行修改
    if (token) {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        config.headers['Authorization'] = `Bearer ${token}`
    }
    return config
}, errorHandler)

// response interceptor
request.interceptors.response.use((response: AxiosResponse<IResponse>) => {
    const { data } = response
    const { getStatus, logout } = useLayoutStore()
    loading.close()
    if (data.code !== 200) {
        let title = '请求失败'
        if (data.code === 401) {
            if (getStatus.ACCESS_TOKEN) {
                logout()
            }
            title = '身份认证失败'
        }
        ElNotification({
            title,
            message: data.message,
            type: 'error'
        })
        return Promise.reject(new Error(data.message || 'Error'))
    }
    return response
}, errorHandler)

export default request
